/*
	Copyright (c) 2012 by karmaleaving@qq.com. All rights RESERVED.
*/
#ifndef __STD_NUMERIC_H_VERSION_KL__
#define __STD_NUMERIC_H_VERSION_KL__
#include "memory.h"
#include "functional.h"
KL_BEGIN
// FUNCTION accumulata {
template<typename InIter, typename Type>
inline Type accumulate(InIter first, InIter last, Type value)
{
	for(; first != last; ++first)
		value = value + *first;
	return value;
}
template<typename InIter, typename Type, typename Plus>
inline Type accumulate(InIter first, InIter last,
					   Type value, Plus fun)
{
	for(; first != last; ++first)
		value = fun(value, *first);
	return value;
}
// FUNCTION accumulata }
// FUNCTION inner_product {
template<typename InputIter1, typename InputIter2, typename Type>
inline Type inner_product(InputIter1 first, InputIter1 last,
						  InputIter2 first2, Type value)
{
	for(; first != last; ++first, ++first2)
		value += *first * * first2;
	return value;
}
template<typename InputIter1, typename InputIter2, 
typename Type, typename Func2>
inline Type inner_product(InputIter1 first, InputIter1 last,
						  InputIter2 first2, Type value, Func2 fun)
{
	for(; first != last; ++first, ++first2)
		value += fun(*first, * first2);
	return value;
}
// FUNCTION inner_product }
// FUNCTION iota {
template<typename OutIter, typename Value>
inline void iota(OutIter first, OutIter last, Value value)
{
	if(first == last) return;
	*first = value;
	while(++first != last) *first = ++value;
}
// FUNCTION iota }
// FUNCTION partial_sum {
template<typename InIter, typename OutIter>
inline OutIter partial_sum(InIter first, InIter last, 
						   OutIter dest)
{
	if(first == last) return dest;
	typename iterator_traits<InIter>::value_type value = *first;
	*dest = value;
	for( ++dest; ++first != last; ++dest)
	{
		*dest = value + *first;
	}
	return dest;
}
template<typename InIter, typename OutIter, typename Plus>
inline OutIter partial_sum(InIter first, InIter last, 
						   OutIter dest, Plus plus)
{
	if(first == last) return dest;
	typename iterator_traits<InIter>::value_type value = *first;
	*dest = value;
	for( ++dest; ++first != last; ++dest)
	{
		*dest = plus(value, *first);
	}
	return dest;
}
// FUNCTION partial_sum }
// FUNCTION power {
template<typename Value>
inline Value power(Value value, int times)
{
	Value result(1);
	while(times--)
	{
		result *= value;
	}
	return result;
}
// FUNCTION power }
KL_END
#endif // __STD_NUMERIC_H_VERSION_KL__
